import axios from 'axios'
import { ElMessage } from 'element-plus'
import router from '../router'

// 创建axios实例
const instance = axios.create({
  baseURL: `${import.meta.env.VITE_API_URL}/api`, // 设置基础URL
  timeout: 30000, // 增加超时时间到30秒
  headers: {
    'Content-Type': 'application/json',
    'X-Requested-With': 'XMLHttpRequest'
  },
  withCredentials: true // 允许跨域请求携带凭证
})

// 处理循环引用的函数
const replacerFunc = () => {
  const visited = new WeakSet();
  return (key, value) => {
    // 如果是对象且不是null
    if (typeof value === "object" && value !== null) {
      // 检查是否已经访问过这个对象
      if (visited.has(value)) {
        return undefined; // 避免循环引用
      }
      visited.add(value);
    }
    return value;
  };
};

// 安全地提取对象的基本属性
const extractSafeData = (obj) => {
  if (!obj) return obj;
  
  // 如果是基本类型，直接返回
  if (typeof obj !== 'object' || obj === null) return obj;
  
  // 如果是数组，递归处理每个元素
  if (Array.isArray(obj)) {
    return obj.map(item => extractSafeData(item));
  }
  
  // 处理对象
  const result = {};
  for (const key in obj) {
    // 跳过函数和Symbol
    if (typeof obj[key] === 'function' || typeof key === 'symbol') continue;
    
    // 跳过以$或_开头的Vue内部属性
    if (key.startsWith('$') || key.startsWith('_')) continue;
    
    // 处理嵌套对象，但限制深度为1，避免过深的递归
    if (typeof obj[key] === 'object' && obj[key] !== null) {
      if (Array.isArray(obj[key])) {
        // 对于数组，只保留基本类型值
        result[key] = obj[key].map(item => 
          typeof item !== 'object' ? item : 
          (item && item.id ? { id: item.id } : undefined)
        ).filter(Boolean);
      } else if (key === 'id' || key.endsWith('_id') || key === 'document_id') {
        // 直接保留ID字段
        result[key] = obj[key];
      } else {
        // 对于其他对象，只保留ID
        result[key] = obj[key] && obj[key].id ? { id: obj[key].id } : undefined;
      }
    } else {
      // 直接复制基本类型值
      result[key] = obj[key];
    }
  }
  return result;
};

// 请求拦截器
instance.interceptors.request.use(
  config => {
    const token = localStorage.getItem('access_token')
    if (token) {
      config.headers['Authorization'] = `Bearer ${token}`
    }
    
    // 如果是文件上传请求，不设置Content-Type，让浏览器自动设置
    if (config.data instanceof FormData) {
      delete config.headers['Content-Type']
    } else if (typeof config.data === 'object' && config.data !== null) {
      // 处理可能的循环引用问题
      try {
        // 先尝试使用安全的方式序列化
        const safeData = extractSafeData(config.data);
        config.data = safeData;
      } catch (e) {
        console.warn('数据序列化警告:', e);
        // 如果出错，创建一个新对象，只包含必要的数据
        const safeData = {};
        for (const key in config.data) {
          if (typeof config.data[key] !== 'object' || config.data[key] === null) {
            safeData[key] = config.data[key];
          } else if (Array.isArray(config.data[key])) {
            // 处理数组
            safeData[key] = [...config.data[key]];
          } else if (key === 'id' || key === 'document_id' || key.endsWith('_id')) {
            // 保留ID字段
            safeData[key] = config.data[key];
          }
        }
        config.data = safeData;
      }
    }
    
    return config
  },
  error => {
    console.error('请求错误:', error)
    return Promise.reject(error)
  }
)

// 响应拦截器
instance.interceptors.response.use(
  response => {
    return response
  },
  async error => {
    if (error.response) {
      const { status, data } = error.response
      
      if (status === 401) {
        // token过期，尝试使用refresh token
        const refreshToken = localStorage.getItem('refresh_token')
        if (refreshToken) {
          try {
            const response = await axios.post(`${import.meta.env.VITE_API_URL}/api/auth/token/refresh/`, {
              refresh: refreshToken
            })
            
            if (response.data.access) {
              localStorage.setItem('access_token', response.data.access)
              error.config.headers['Authorization'] = `Bearer ${response.data.access}`
              return instance(error.config)
            }
          } catch (refreshError) {
            // refresh token也过期，需要重新登录
            localStorage.removeItem('access_token')
            localStorage.removeItem('refresh_token')
            router.push('/login')
            ElMessage.error('登录已过期，请重新登录')
          }
        } else {
          router.push('/login')
          ElMessage.error('请先登录')
        }
      } else if (status === 500) {
        ElMessage.error('服务器错误，请稍后重试')
      }
      
      return Promise.reject(error)
    }
    return Promise.reject(error)
  }
)

export default instance 